import cv2
import numpy as np
from PyQt5.QtWidgets import (QMainWindow, QFileDialog, QVBoxLayout, QWidget,
                             QPushButton, QSlider, QLabel, QMessageBox, QComboBox)
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import Qt, QTimer
import os


class ComputerVisionApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.image = None
        self.video_capture = None
        self.is_video_playing = False
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_video_frame)
        self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

    def initUI(self):
        self.setWindowTitle('计算机视觉开发平台')
        self.setGeometry(100, 100, 1200, 800)

        # 主界面布局
        self.central_widget = QWidget(self)
        self.setCentralWidget(self.central_widget)
        layout = QVBoxLayout()

        # 图像显示区域
        self.image_label = QLabel(self)
        self.image_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.image_label)

        # 控制面板
        self.create_control_panel(layout)
        self.central_widget.setLayout(layout)

        # 菜单栏
        self.create_menu_bar()

    def create_menu_bar(self):
        menubar = self.menuBar()

        # 文件菜单
        file_menu = menubar.addMenu('文件')
        file_menu.addAction('打开图像', self.open_image)
        file_menu.addAction('打开视频', self.open_video)
        file_menu.addAction('保存图像', self.save_image)
        file_menu.addAction('退出', self.close)

        # 编辑菜单
        edit_menu = menubar.addMenu('编辑')
        edit_menu.addAction('旋转', self.rotate_image)
        edit_menu.addAction('缩放', self.scale_image)
        edit_menu.addAction('裁剪', self.crop_image)

        # 处理菜单
        process_menu = menubar.addMenu('处理')
        process_menu.addAction('灰度化', self.convert_to_grayscale)
        process_menu.addAction('边缘检测', self.edge_detection)
        process_menu.addAction('人脸检测', self.face_detection)

    def create_control_panel(self, layout):
        # 图像处理按钮
        self.grayscale_btn = QPushButton('灰度化', self)
        self.grayscale_btn.clicked.connect(self.convert_to_grayscale)
        layout.addWidget(self.grayscale_btn)

        # 参数调节滑块
        self.brightness_slider = QSlider(Qt.Horizontal)
        self.brightness_slider.setRange(-100, 100)
        self.brightness_slider.valueChanged.connect(self.adjust_brightness)
        layout.addWidget(QLabel('亮度调节'))
        layout.addWidget(self.brightness_slider)

        # 视频控制按钮
        self.play_btn = QPushButton('播放', self)
        self.play_btn.clicked.connect(self.toggle_video_playback)
        layout.addWidget(self.play_btn)

    def open_image(self):
        file_name, _ = QFileDialog.getOpenFileName(self, "打开图像", "", "Image Files (*.png *.jpg *.bmp)")
        if file_name:
            self.image = cv2.imread(file_name)
            self.display_image(self.image)

    def display_image(self, image):
        if image is not None:
            height, width, channel = image.shape
            bytes_per_line = 3 * width
            q_img = QImage(image.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
            self.image_label.setPixmap(QPixmap.fromImage(q_img))

    def convert_to_grayscale(self):
        if self.image is not None:
            gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
            self.display_image(cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR))

    def face_detection(self):
        if self.image is not None:
            gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
            faces = self.face_cascade.detectMultiScale(gray, 1.3, 5)
            for (x, y, w, h) in faces:
                cv2.rectangle(self.image, (x, y), (x + w, y + h), (255, 0, 0), 2)
            self.display_image(self.image)

    def open_video(self):
        file_name, _ = QFileDialog.getOpenFileName(self, "打开视频", "", "Video Files (*.mp4 *.avi)")
        if file_name:
            self.video_capture = cv2.VideoCapture(file_name)
            self.is_video_playing = True
            self.timer.start(30)

    def toggle_video_playback(self):
        if self.video_capture is not None:
            self.is_video_playing = not self.is_video_playing
            if self.is_video_playing:
                self.timer.start(30)
                self.play_btn.setText('暂停')
            else:
                self.timer.stop()
                self.play_btn.setText('播放')

    def update_video_frame(self):
        ret, frame = self.video_capture.read()
        if ret:
            self.display_image(frame)
        else:
            self.timer.stop()
            self.is_video_playing = False
            self.play_btn.setText('播放')

    def save_image(self):
        if self.image is not None:
            file_name, _ = QFileDialog.getSaveFileName(self, "保存图像", "", "PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp)")
            if file_name:
                cv2.imwrite(file_name, self.image)
